package com.rq.base.ui;

import android.text.TextUtils;
import android.view.View;

import com.rq.base.ui.impl.CtrListener;
import com.rq.base.ui.impl.CtrTag;
import com.rq.base.util.LOG;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 控制器集中管理
 * watch 、 send 实现类似于 EventBus 进行 Controller 之间的数据传递
 */
public class CtrWatcher {

    private static CtrWatcher mCtrWatcher;
    HashMap<String, CtrListener> watcher = new HashMap<>();
    List<CtrListener> visibleFragmentController = new ArrayList<>();
    CtrListener visibleActivityController = null;

    private CtrWatcher() {
    }

    public static CtrWatcher get() {
        if (mCtrWatcher == null) {
            synchronized (CtrWatcher.class) {
                if (mCtrWatcher == null) {
                    mCtrWatcher = new CtrWatcher();
                }
            }
        }
        return mCtrWatcher;
    }

    public void watch(String tag, CtrListener controller) {
        if (!TextUtils.isEmpty(tag)) {
            LOG.e("CtrWatcher", tag + ".watch--->:" + controller.getClass().getSimpleName());
            watcher.put(tag + controller.hashCode(), controller);
        }
    }

    public void removeWatch(Object controller) {
        if (controller instanceof CtrListener) {
            Method method = null;
            try {
                method = ((CtrListener) controller).getClass().getMethod("tagInfo", String.class, Object[].class);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            if (method != null) {
                Annotation[] annotations = method.getAnnotations();
                if (annotations.length > 0) {
                    for (Annotation annotation : annotations) {
                        if (annotation instanceof CtrTag) {
                            LOG.e("CtrWatcher", "onViewCreated.494:" + annotation.toString());
                            CtrTag inject = (CtrTag) annotation;
                            String[] tags = inject.value();
                            for (String tag : tags) {
                                watcher.remove(tag + controller.hashCode());
                            }
                        }
                    }
                }
            }
        }
    }

    public List<CtrListener> getAllVisibleController() {
        List<CtrListener> all = new ArrayList<>();
        all.add(visibleActivityController);
        all.addAll(visibleFragmentController);
        return all;
    }

    public List<CtrListener> getVisibleFragmentController() {
        return visibleFragmentController;
    }

    public CtrListener getVisibleActivityController() {
        return visibleActivityController;
    }

    public void addActivityController(Object controller) {
        if (controller instanceof CtrListener)
            this.visibleActivityController = (CtrListener) controller;
    }

    public void removerActivityController(Object controller) {
        this.visibleActivityController = null;
    }

    public void addFragmentController(Object controller) {
        LOG.d("CtrWatcher", "AddFra : " + controller.getClass().getSimpleName());
        if (controller instanceof CtrListener)
            visibleFragmentController.add((CtrListener) controller);
        LOG.d("CtrWatcher", "Res : " + visibleFragmentController.size());
    }

    public void removerFragmentController(Object controller) {
        if (controller instanceof CtrListener)
            visibleFragmentController.remove(controller);
    }

    public void post(String tag, Object... object) {
        if (object.length > 0) {
            LOG.e("CtrWatcher", watcher.size() + ".send" + object[0]);
        } else {
            LOG.e("CtrWatcher", watcher.size() + ".send.no.data");
        }
        for (String key : watcher.keySet()) {
            if (key.contains(tag)) {
                CtrListener controller = watcher.get(key);
                if (controller != null) {
                    LOG.e("CtrWatcher", key + ".send.ok:" + controller.getClass().getSimpleName());
                    controller.tagInfo(tag, object);
                } else {
                    LOG.e("CtrWatcher", key + ".send.stop");
                }
            } else {
                LOG.e("CtrWatcher", key + ".send.stop");
            }
        }
    }

    public void notifyFragmentOnResume() {
        for (CtrListener item : CtrWatcher.get().getVisibleFragmentController()) {
            if (item instanceof BaseController) {
                ((BaseController) item).onResume();
            }
        }
    }

    public CtrListener findController(Class<?> attach) {
        if (attach != null && getAllVisibleController() != null) {
            for (CtrListener CtrListener : getAllVisibleController()) {
                if (CtrListener.getClass() == attach) {
                    return CtrListener;
                }
            }
        }
        return null;
    }
}
